package com.yuke.cloud.service.omc.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.yuke.cloud.common.base.constant.GlobalConstant;
import com.yuke.cloud.common.base.constant.MQConstants;
import com.yuke.cloud.common.base.dto.MsgNotificationBody;
import com.yuke.cloud.common.core.mq.RabbitMetaMessage;
import com.yuke.cloud.common.core.mq.RabbitSender;
import com.yuke.cloud.common.core.support.BaseService;
import com.yuke.cloud.common.util.BigDecimalUtil;
import com.yuke.cloud.common.util.PublicUtil;
import com.yuke.cloud.common.util.wrapper.WrapMapper;
import com.yuke.cloud.common.util.wrapper.Wrapper;
import com.yuke.cloud.service.api.cmc.dto.CmsCouponGoodsDto;
import com.yuke.cloud.service.api.cmc.dto.CmsCouponUserDto;
import com.yuke.cloud.service.api.cmc.dto.CmsSysInfoDto;
import com.yuke.cloud.service.api.cmc.service.CmcFeignApi;
import com.yuke.cloud.service.api.opc.service.OpcSendNotifyFeignApi;
import com.yuke.cloud.service.api.smc.dto.ShopInfoDto;
import com.yuke.cloud.service.api.smc.service.SmcFeignApi;
import com.yuke.cloud.service.api.uac.dto.UserInfoDto;
import com.yuke.cloud.service.api.uac.service.UacUserFeignApi;
import com.yuke.cloud.service.api.wmc.dto.StorageDto;
import com.yuke.cloud.service.api.wmc.dto.StorageSpecInfoDto;
import com.yuke.cloud.service.api.wmc.dto.WmsGiftDto;
import com.yuke.cloud.service.api.wmc.service.WmcStorageFeignApi;
import com.yuke.cloud.service.omc.config.Quartz;
import com.yuke.cloud.service.omc.controller.frontend.PayController;
import com.yuke.cloud.service.omc.dao.OdsPayOrderMapper;
import com.yuke.cloud.service.omc.entity.*;
import com.yuke.cloud.service.omc.service.*;
import io.swagger.annotations.ApiParam;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


/**
 * Created by zys on 2018/12/10.
 */
@Service
@Transactional
public class OdsPayOrderServiceImpl extends BaseService<OdsPayOrder> implements OdsPayOrderService {
    @Resource
    private OdsPayOrderMapper odsPayOrderMapper;
    @Resource
    private OdsPayOrderService odsPayOrderService;
    @Resource
    private OdsOrderGoodsService odsOrderGoodsService;
    @Resource
    private OdsOrderService odsOrderService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RabbitSender rabbitSender;
    @Resource
    private OdsStockGoodsService odsStockGoodsService;
    @Resource
    private OdsStockOrderService odsStockOrderService;
    @Autowired
    private OpcSendNotifyFeignApi opcSendNotifyFeignApi;
    @Autowired
    private SmcFeignApi smcFeignApi;
    @Resource
    private WmcStorageFeignApi wmcStorageFeignApi;
    @Resource
    private CmcFeignApi cmcFeignApi;


    private static final Logger LOG = Logger.getLogger(PayController.class);

    @Override
    public void deleteByOrderIds(String orderIds) {
        Example example = new Example(OdsPayOrder.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andLike("orderIds", "%" + orderIds + "%");
        odsPayOrderMapper.deleteByExample(example);
    }

    @Override
    public void doPayOrderProcess(Map<String,String> params){
        String orderIds = super.findById(Long.valueOf(params.get("out_trade_no"))).getOrderIds();
        String[] split = orderIds.split(",");
        String total_amount = params.get("total_amount");

            if (params.get("body").equals("shopnosend")) {
                doShopNoSendProgress(split,total_amount);

            }
            if (params.get("body").equals("normal")) {
                doNormalProgress(split,total_amount);
            }
            if (params.get("body").equals("shopsend")) {
                doShopSendProgress(split,total_amount);
            }

    }

    private void doShopNoSendProgress(String[] split,String total_amount){
        //**店铺购买划拨
        redisTemplate.delete("second:" + split[0]);
        OdsStockOrder odsStockOrder = new OdsStockOrder();
        odsStockOrder.setStockOrderId(Long.valueOf(split[0]));
        odsStockOrder.setPayTime(new Date());
        odsStockOrder.setPayStatus((byte) 1);
        double v = Double.parseDouble(total_amount);
        double v1 = BigDecimalUtil.mul(v, 100).doubleValue();
        odsStockOrder.setAmountPaid((int) v1);
        odsStockOrder.setStockStatus((byte) 1);//1已确认表示没有发货，已完成表示已经入库
        odsStockOrderService.update(odsStockOrder);
        //todo 调用feign接口划拨对应商店的仓库地址
        OdsStockGoods odsStockGoods = new OdsStockGoods();
        System.out.println(Long.valueOf(split[0]));
        odsStockGoods.setStockOrderId(Long.valueOf(split[0]));
        List<OdsStockGoods> select = odsStockGoodsService.select(odsStockGoods);
        OdsStockGoods byId1 = select.get(0);
        Date inboundPlanTime = byId1.getInboundPlanTime();
        if (inboundPlanTime != null && inboundPlanTime.getDay() == new Date().getDay()) {
            List<Map> list = new ArrayList<Map>();
            List<Long> list1 = new ArrayList<>();
            Long shopid = null;
            for (int i = 0; i < select.size(); i++) {
                Map map = new HashMap();
                OdsStockGoods odsStockGoods1 = select.get(i);
                if (System.currentTimeMillis() >= odsStockGoods1.getInboundPlanTime().getTime()) {

                    Long orderId = odsStockGoods1.getStockOrderId();
                    OdsStockOrder byId = odsStockOrderService.findById(orderId);
                    Long shopId = byId.getShopId();
                    shopid = shopId;
                    Long specId = odsStockGoods1.getSpecId();
                    Integer goodsNum = odsStockGoods1.getStockNumber();
                    list1.add(odsStockGoods1.getStockGoodsId());
                    map.put("shopId", shopId);
                    map.put("specId", specId);
                    //已经付款，总仓库数量不变，店铺下面的商品变多
                    map.put("goodsNum", goodsNum);
                    list.add(map);
                }
            }
            String ss = JSON.toJSONString(list);

            smcFeignApi.updateStockCount(ss);
            //添加具体入库时间
            for (int i = 0; i < list1.size(); i++) {
                OdsStockGoods odsStockGoods1 = new OdsStockGoods();
                odsStockGoods1.setStockGoodsId(list1.get(i));
                odsStockGoods1.setInboundTime(new Date());
                odsStockGoods1.setGoodsStatus((byte)1);
                odsStockGoodsService.update(odsStockGoods1);
            }
            MsgNotificationBody msg = new MsgNotificationBody();
            msg.setTitle("发货通知");
            msg.setContent("您的进货订单" + split[0] + "已经划拨发货");
            msg.setTime(new Date());
            msg.setReceiveType((byte) 3);
            msg.setOrderType((byte) 1);
            msg.setMsgType("orderMsg");
            List<Long> list2 = new ArrayList<>();
            list2.add(shopid);
            Long userId = smcFeignApi.getShopUserIdByShopIds(list2).get(0).getUserId();
            opcSendNotifyFeignApi.sendnotify(userId.toString(), "发货通知", "您的进货订单" + split[0] + "已经发货", 0);
            opcSendNotifyFeignApi.sendnotify(userId.toString(), "发货通知", JSON.toJSONString(msg), 1);
        }
    }

    private void doNormalProgress(String[] split,String total_amount){
        StringBuilder sb = new StringBuilder();
        List<Map> list = new ArrayList<>();
        List<Long> shopIds = new ArrayList<>(); // add by wg 20190516 保存店铺信息
        List<OdsOrder> odsOrders = new ArrayList<>(); // add by wg 20190516 保存订单信息
        for (int i = 0; i < split.length; i++) {
            OdsOrder byId2 = odsOrderService.findById(Long.valueOf(split[i]));

            // add by wg 20190711 增加货到付款处理
            if (byId2.getPayType() != 0) {
                redisTemplate.delete("zero:" + split[i]);
            }

            //todo 第一删除redis里面的key，第二修改订单的状态
            OdsOrder odsOrder = new OdsOrder();
            odsOrder.setOrderId(Long.valueOf(split[i]));
            odsOrder.setPayStatus((byte) 1);
            odsOrder.setPayType((byte)2);  // add by wg 20190711
            odsOrder.setPayTime(new Date());

            // add by wg 20190711 增加货到付款处理
            if (byId2.getPayType() == 0) {  // 货到付款
                odsOrder.setShippingStatus((byte) 3);
                odsOrder.setOrderStatus((byte) 2);
            } else {
                odsOrder.setShippingStatus((byte) 0);
                odsOrder.setOrderStatus((byte) 1);
            }

            if (byId2 != null) {
                odsOrder.setAmountPaid(byId2.getAmountPayable());
            } else {
                double v = Double.parseDouble(total_amount);
                // mod by wg 20190413
                // double v1 = v * 100;
                double v1 = BigDecimalUtil.mul(v, 100).doubleValue();
                odsOrder.setAmountPaid((int) v1);
            }


            //保存到数据库，修改订单状态为已付款，未发货
            odsOrderService.update(odsOrder);

            // add by wg 20190711 增加货到付款处理
            if (byId2.getPayType() != 0) {
                String a = String.valueOf(byId2.getShopId());
                if (i == split.length - 1) {
                    sb.append(a);
                } else {
                    sb.append(a + ",");
                }

                shopIds.add(byId2.getShopId());
                if (byId2.getIsFactory()) {
                    shopIds.add(byId2.getFactoryShopId());
                }
                odsOrders.add(byId2);
            }
        }

        // add by wg 20190711 增加货到付款处理
        if (odsOrders.size() > 0) {
            // mod by wg 20190516 V1.1版，如果配送类型是同城发送时，直接通知仓库发货，或者配送类型是仓库配送的即时达类型也由仓库发货
            // 获取店铺信息
            System.out.println("CDS+++++++++odspayserviceImpl=++++++++shopInfoDtoList="+shopIds);
            List<ShopInfoDto> shopInfoDtos = smcFeignApi.getShopInfoByShopIds(shopIds);
            for (OdsOrder odsOrder : odsOrders) {
                if (odsOrder.getShippingType() == 0) {  // 同城即时达
                    for (ShopInfoDto shopInfoDto : shopInfoDtos) {
                        if (odsOrder.getShopId().equals(shopInfoDto.getShopId()) && shopInfoDto.getShopType() == 1) {  // 店铺类型为云顶店铺
                            MsgNotificationBody msg = new MsgNotificationBody();
                            msg.setTitle("订单处理");
                            msg.setContent("您的店铺有订单需要处理");
                            msg.setTime(new Date());
                            msg.setReceiveType((byte) 3);
                            msg.setOrderType((byte) 1);
                            msg.setMsgType("orderMsg");
                            Long userId = shopInfoDto.getUserId();
                            opcSendNotifyFeignApi.sendnotify(userId.toString(), "订单处理", "您的店铺有订单需要处理", 0);
                            opcSendNotifyFeignApi.sendnotify(userId.toString(), "订单处理", JSON.toJSONString(msg), 1);

                            break;
                        } else if (odsOrder.getShopId().equals(shopInfoDto.getShopId()) && shopInfoDto.getShopType() == 4) {  // 直营店铺
                            //同时通知仓库(用rabbitmq发送)，有新订单需要打印
                            //同时通知仓库(用rabbitmq发送)，有新订单需要打印
                            sendMsgToWarehouse(odsOrder.getShopId().toString(), null);
                        }
                    }
                } else if (odsOrder.getIsFactory()) {  // 厂家直销订单，直接通知厂家发货
                    for (ShopInfoDto shopInfoDto : shopInfoDtos) {
                        if (odsOrder.getFactoryShopId().equals(shopInfoDto.getShopId()) && shopInfoDto.getShopType() == 3) {  // 店铺类型为云顶店铺
                            MsgNotificationBody msg = new MsgNotificationBody();
                            msg.setTitle("订单处理");
                            msg.setContent("您有订单需要发货");
                            msg.setTime(new Date());
                            msg.setReceiveType((byte) 3);
                            msg.setOrderType((byte) 1);
                            msg.setMsgType("orderMsg");
                            Long userId = shopInfoDto.getUserId();
                            opcSendNotifyFeignApi.sendnotify(userId.toString(), "订单处理", "您有订单需要发货", 0);
                            opcSendNotifyFeignApi.sendnotify(userId.toString(), "订单处理", JSON.toJSONString(msg), 1);

                            break;
                        }
                    }
                } else if (odsOrder.getShippingType() == 2) { // 同城快送
                    //同时通知仓库(用rabbitmq发送)，有新订单需要打印
                    sendMsgToWarehouse(odsOrder.getShopId().toString(), null);
                } else if (odsOrder.getWarehouseId() != null){  // add by wg 20190717
                    sendMsgToWarehouse(null, odsOrder.getWarehouseId().toString());
                }
            }
        }
    }
    private void doShopSendProgress(String[] split,String total_amount){
        StringBuilder sb = new StringBuilder();
        List<Map> list = new ArrayList<>();
        for (int i = 0; i < split.length; i++) {
            OdsOrder odsOrder1 = odsOrderService.findById(Long.valueOf(split[i]));

            // add by wg 20190711 增加货到付款处理
            if (odsOrder1.getPayType() != 0) {
                redisTemplate.delete("first:" + split[i]);
            }

            OdsOrder odsOrder = new OdsOrder();
            odsOrder.setOrderId(Long.valueOf(split[i]));
            odsOrder.setPayType((byte)2);  // add by wg 20190711
            odsOrder.setPayStatus((byte) 1);
            odsOrder.setPayTime(new Date());

            // add by wg 20190711 增加货到付款处理
            if (odsOrder1.getPayType() == 0) {  // 货到付款
                odsOrder.setShippingStatus((byte) 3);
                odsOrder.setOrderStatus((byte) 2);
            } else {
                odsOrder.setShippingStatus((byte) 0);
                odsOrder.setOrderStatus((byte) 1);
            }

            if (odsOrder1 != null) {
                odsOrder.setAmountPaid(odsOrder1.getAmountPayable());
            } else {
                // mod by wg 20190413
//                            double v = Double.parseDouble(total_amount) * 100;
                double v = BigDecimalUtil.mul(Double.parseDouble(total_amount), 100).doubleValue();
                odsOrder.setAmountPaid((int) v);
            }

            //保存到数据库，修改订单状态为已付款，未发货
            //店铺预定，但是发货，已经减少了
            // todo 目前对于返利结算直接在订单中优惠，因此此时直接将是否返利字段置为true，20190727
            odsOrder.setIsCheckout(true);

            odsOrderService.update(odsOrder);


            // add by wg 20190711 增加货到付款处理
            if (odsOrder1.getPayType() != 0) {
                String a = String.valueOf(odsOrder1.getShopId());
                if (i == split.length - 1) {
                    sb.append(a);
                } else {
                    sb.append(a + ",");
                }
            }
        }

        // add by wg 20190711 增加货到付款处理
        if (PublicUtil.isNotEmpty(sb)) {
            Map map = new HashMap();
            map.put("MessageType", "findWarehouseAdmin");
            map.put("shopIds", sb.toString());
            map.put("body", "你有新的订单需要发货");//"查找仓库管理员");
            RabbitMetaMessage rabbitMetaMessage = new RabbitMetaMessage();
            rabbitMetaMessage.setExchange(MQConstants.BUSINESS_EXCHANGE);
            rabbitMetaMessage.setRoutingKey(MQConstants.BUSINESS_KEY_WMC);
            rabbitMetaMessage.setPayload(JSON.toJSONString(map));
            try {
                rabbitSender.send(rabbitMetaMessage);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public void sendMsgToWarehouse(String shopIds, String warehouseIds) {
        Map map = new HashMap();
        map.put("MessageType", "findWarehouseAdmin");
        map.put("shopIds", shopIds);
        map.put("warehouseIds", warehouseIds);
        map.put("body", "你有新的订单需要发货");//"查找仓库管理员");
        RabbitMetaMessage rabbitMetaMessage = new RabbitMetaMessage();
        rabbitMetaMessage.setExchange(MQConstants.BUSINESS_EXCHANGE);
        rabbitMetaMessage.setRoutingKey(MQConstants.BUSINESS_KEY_WMC);
        rabbitMetaMessage.setPayload(JSON.toJSONString(map));
        try {
            rabbitSender.send(rabbitMetaMessage);
        } catch (Exception e) {
            LOG.error("rabbitSender.send()调用异常");
        }
    }

    @Override
    public void changePayOrderStatus(Long intentId){
        Example example = new Example(OdsPayOrder.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderIds",intentId.toString());
        criteria.andGreaterThan("amountPaid",0);

        List<OdsPayOrder> odsPayOrderList =  this.selectByExample(example);
        for (OdsPayOrder odsPayOrder : odsPayOrderList){
            odsPayOrder.setAmountPaid(0);
            this.update(odsPayOrder);
        }
    }

    @Override
    public Wrapper<OdsOrder> getRealMoney(OdsOrder odsOrder) {

        Integer totalMoney = 0;
        Integer rebateMoney = 0;

        float discount = 1;
        float businessDiscount = 1;
        float rebate = 0;

        Integer reachMoney = 0;
        Integer returnMoney = 0;

        Integer reachOne = 0;
        Integer reachTwo = 0;
        Integer reachThree = 0;
        Integer returnOne = 0;
        Integer returnTwo = 0;
        Integer returnThree = 0;

        Long groupId = odsOrder.getGroupId();

        Long shopId = odsOrder.getShopId();
        Long shopGroupId = 220839532667469824L;
        Wrapper wrap = wmcStorageFeignApi.getGroupIdByShopId(shopId);
        if (wrap.getCode() == 200 && wrap.getResult() != null) {
            shopGroupId = Long.valueOf(wrap.getResult().toString());
        }

        CmsSysInfoDto cmsSysInfo = cmcFeignApi.getSysInfoDtoByType(shopGroupId, GlobalConstant.SysInfo.SYS_INFO_DISCOUNT);
        //获得打折标准
        if (cmsSysInfo != null && cmsSysInfo.getStatus() > 0) {
            discount = Float.parseFloat(cmsSysInfo.getInfoValue());
        }

        //获得B端用户C端打折标准
        CmsSysInfoDto cmsBusinessDiscount = cmcFeignApi.getSysInfoDtoByType(shopGroupId, GlobalConstant.SysInfo.SYS_INFO_BUSINESS_DISCOUNT);
        if (cmsBusinessDiscount != null && cmsBusinessDiscount.getStatus() > 0) {
            businessDiscount = Float.parseFloat(cmsBusinessDiscount.getInfoValue());
        }

        //获得返利标准
        CmsSysInfoDto cmsSysInfoRebate = cmcFeignApi.getSysInfoDtoByType(shopGroupId, GlobalConstant.SysInfo.SYS_INFO_REBATE);
        if (cmsSysInfoRebate != null && cmsSysInfoRebate.getStatus() > 0) {
            rebate = Float.parseFloat(cmsSysInfoRebate.getInfoValue());
        }


        //获得满减标准
        CmsSysInfoDto cmsSysInfoDeduce = cmcFeignApi.getSysInfoDtoByType(shopGroupId, GlobalConstant.SysInfo.SYS_INFO_DEDUCE);
        if (cmsSysInfoDeduce != null && cmsSysInfoDeduce.getStatus() > 0) {
            JSONObject jsonObject = JSON.parseObject(cmsSysInfoDeduce.getInfoValue());
            reachMoney = jsonObject.getInteger("reachMoney");
            returnMoney = jsonObject.getInteger("returnMoney");
        }

        //获得B端满减标准
        CmsSysInfoDto cmsBusDeduce = cmcFeignApi.getSysInfoDtoByType(shopGroupId, 21);
        if (cmsBusDeduce != null && cmsBusDeduce.getStatus() > 0) {
            JSONObject jsonObject = JSON.parseObject(cmsBusDeduce.getInfoValue());
            reachOne = jsonObject.getInteger("reachOne");
            reachTwo = jsonObject.getInteger("reachTwo");
            reachThree = jsonObject.getInteger("reachThree");
            returnOne = jsonObject.getInteger("returnOne");
            returnTwo = jsonObject.getInteger("returnTwo");
            returnThree = jsonObject.getInteger("returnThree");
        }

        List<OdsOrderGoods> odsOrderGoodsList = odsOrder.getGoodsList();
        List<Long> specIds = odsOrderGoodsList.stream().map(OdsOrderGoods::getSpecId).collect(Collectors.toList());
        List<StorageSpecInfoDto> storageSpecInfoDtos = wmcStorageFeignApi.getWmsSpecInfoBySpecIds(specIds, shopId);
        List<OdsOrderGoods> cmsSpecDtoList = new ArrayList<>();

        if (storageSpecInfoDtos != null && storageSpecInfoDtos.size() > 0) {
            if (odsOrderGoodsList != null && odsOrderGoodsList.size() > 0) {
                if (odsOrder.getOrderType() == null) {
                    odsOrder.setOrderType((byte) 2);
                }
                float price = 0;
                for (OdsOrderGoods cmsSpecDto : odsOrderGoodsList) {
                    if (cmsSpecDto.getGoodsStatus() != null && cmsSpecDto.getGoodsStatus().equals((byte) 4)) {
                        cmsSpecDto.setPayPrice(0);
                        cmsSpecDto.setGoodsNum(0);
                        continue;
                    }
                    cmsSpecDto.setPayPrice(cmsSpecDto.getGoodsPrice());
                    for (StorageSpecInfoDto prodSpecInfoDto : storageSpecInfoDtos) {
                        if (cmsSpecDto.getSpecId().equals(prodSpecInfoDto.getSpecId())) {
                            totalMoney += cmsSpecDto.getGoodsPrice() * cmsSpecDto.getGoodsNum();
                            //1.该商品是否打折
                            if (prodSpecInfoDto.getHasDiscount() > 0) {
                                //订单为消费者下单，可打折
                                if (odsOrder.getOrderType().toString().equals("1")) {
                                    //如果商家用户、云顶商人在C端下单打7折，否则按C端的正常折扣
                                    if (groupId > 4) {
                                        cmsSpecDto.setPayPrice(Math.round(cmsSpecDto.getGoodsPrice() * businessDiscount));
                                    } else {
                                        cmsSpecDto.setPayPrice(Math.round(cmsSpecDto.getGoodsPrice() * discount));
                                    }

                                }
                            }

                            //2.是否有搭赠,搭赠不参加返利
                            boolean tag = false;
                            if (!prodSpecInfoDto.getHasTying()) {
                                //3.是否返利
                                if (prodSpecInfoDto.getHasRebate() > 0) {

                                    //订单为店家可返利
                                    if (odsOrder.getOrderType().toString().equals("2")) {
                                        cmsSpecDto.setPayPrice(Math.round(cmsSpecDto.getGoodsPrice() * (1 - rebate)));
                                        cmsSpecDto.setGoodsAttribute("1");
                                        tag = true;
                                    }
                                }
                            }
                            if (tag) {
                                price += cmsSpecDto.getGoodsPrice() * cmsSpecDto.getGoodsNum() * (1 - rebate);

                            } else {
                                price += cmsSpecDto.getPayPrice() * cmsSpecDto.getGoodsNum();
                            }

                            System.out.println("商品信息cmsSpecDto2:" + cmsSpecDto);
                            cmsSpecDtoList.add(cmsSpecDto);
                            break;
                        }//if id=id
                    }//for
                }//for
                rebateMoney = Math.round(price);
                odsOrder.setDiscountMoney(totalMoney - rebateMoney);
                //4.是否满减 满减活动是否开启 满减是针对C端
                if (reachMoney > 0) {
                    if (odsOrder.getOrderType().toString().equals("1")) {
                        if (rebateMoney >= reachMoney) {

                            for (OdsOrderGoods cmsSpecDto : cmsSpecDtoList) {
                                cmsSpecDto.setPayPrice(Math.round(cmsSpecDto.getPayPrice() - cmsSpecDto.getPayPrice() * returnMoney / rebateMoney));
                            }

                            rebateMoney = rebateMoney - returnMoney;
                            odsOrder.setReductionMoney(returnMoney);
                        }
                    }
                }
                //5.是否满减 满减活动是否开启 满减是针对B端
                if (reachOne != null && reachOne > 0) {
                    if (odsOrder.getOrderType().toString().equals("2")) {
                        if (rebateMoney >= reachThree) {
                            returnMoney = returnThree;
                        } else if (rebateMoney >= reachTwo) {
                            returnMoney = returnTwo;
                        } else if (rebateMoney >= reachOne) {
                            returnMoney = returnOne;
                        }
                        if(rebateMoney > 0 && returnMoney > 0){
                            for (OdsOrderGoods cmsSpecDto : cmsSpecDtoList) {
                                float rate = (float)returnMoney / rebateMoney;
                                cmsSpecDto.setPayPrice(Math.round(cmsSpecDto.getPayPrice() *(1- rate) ));

                            }
                        }

                        rebateMoney = rebateMoney - returnMoney;
                        odsOrder.setReductionMoney(returnMoney);
                    }
                }

            }//if
        } else {
            return WrapMapper.error("该商品未找到，可能被禁用");
        }//if
        //更新订单信息
        odsOrder.setAmountPayable(rebateMoney);
        odsOrder.setProductPriceTotal(totalMoney);
        odsOrder.setDiscount(totalMoney - rebateMoney);
        odsOrder.setGoodsList(cmsSpecDtoList);
        //添加赠品
        getGiftSpecList(odsOrder);
        return WrapMapper.ok(odsOrder);
    }

    @Override
    public Wrapper<OdsOrder> getGiftSpecList(@ApiParam(name = "odsOrder", value = "需要修改的内容") @RequestBody OdsOrder odsOrder) {
        List<OdsOrderGoods> cmsSpecDtoList = new ArrayList<>();

        if (odsOrder.getGoodsList() != null && odsOrder.getGoodsList().size() > 0) {

            WmsGiftDto wmsGift = new WmsGiftDto();
            wmsGift.setWarehouseId(odsOrder.getWarehouseId());
            List<WmsGiftDto> wmsGiftDtoList = wmcStorageFeignApi.getGiftList(wmsGift);
            System.out.println("获得赠品列表" + wmsGiftDtoList);
            if (wmsGiftDtoList == null || wmsGiftDtoList.size() < 1) {
                return WrapMapper.ok(odsOrder);
            }


            for (OdsOrderGoods orderSpec : odsOrder.getGoodsList()) {

                for (WmsGiftDto wmsGiftDto : wmsGiftDtoList) {

                    if (orderSpec.getSpecId().equals(wmsGiftDto.getSpecId())) {
                        int num = 0;
                        //1.是否达到购买数量
                        if (wmsGiftDto.getNumber() > 0 && orderSpec.getGoodsNum() < wmsGiftDto.getNumber()) {
                            break;
                        }
                        //2.是否达到购买金额
                        if (wmsGiftDto.getFee() > 0 && orderSpec.getGoodsNum() * orderSpec.getGoodsPrice() < wmsGiftDto.getFee()) {
                            break;
                        }
                        //3.赠品是否还有库存
                        if (wmsGiftDto.getStockNumber() - wmsGiftDto.getOutNumber() < orderSpec.getGoodsNum()) {
                            break;
                        }
                        //4.计算出库数量
                        if (wmsGiftDto.getNumber() > 0) {
                            num = (int) Math.floor(orderSpec.getGoodsNum() / wmsGiftDto.getNumber());
                        } else if (wmsGiftDto.getFee() > 0) {
                            num = (int) Math.floor(wmsGiftDto.getFee() / orderSpec.getGoodsNum() * orderSpec.getGoodsPrice());
                        }

                        OdsOrderGoods orderGoods = new OdsOrderGoods();
                        orderGoods.setGiftId(wmsGiftDto.getGiftId());
                        orderGoods.setSpecId(wmsGiftDto.getGiftSpecId());
                        orderGoods.setSpecName(wmsGiftDto.getGiftSpecName());
                        orderGoods.setProductId(wmsGiftDto.getProductId());
                        orderGoods.setGoodsWeight(wmsGiftDto.getWeight());
                        orderGoods.setPrice(0);
                        orderGoods.setPayPrice(0);
                        orderGoods.setGoodsStatus((byte) 4);
                        if (num > 0) {
                            orderGoods.setGoodsNum(wmsGiftDto.getGiftNum() * num);
                            wmsGiftDto.setOutNumber(wmsGiftDto.getGiftNum() * num);
                        }

                        if (cmsSpecDtoList.size() > 0) {
                            Boolean tag = true;
                            for (OdsOrderGoods item : cmsSpecDtoList) {
                                if (item.getSpecId().equals(orderGoods.getSpecId())) {
                                    tag = false;
                                    item.setGoodsNum(orderGoods.getGoodsNum() + item.getGoodsNum());
                                }
                            }
                            if (tag) {
                                cmsSpecDtoList.add(orderGoods);
                            }
                        } else {
                            cmsSpecDtoList.add(orderGoods);
                        }

                        //5.赠品出库，赠品表出库(商品库存表在提交订单时处理)
                        String key = "Order:" + odsOrder.getOrderId() + ":SpecId" + wmsGiftDto.getSpecId();
                        redisTemplate.opsForValue().set(key, wmsGiftDto, Quartz.second, TimeUnit.SECONDS);

                        break;
                    }
                }//for

            }//for
            odsOrder.getGoodsList().addAll(cmsSpecDtoList);
        }

        return WrapMapper.ok(odsOrder);
    }

    @Override
    public void changeGiftNumber(OdsOrderGoods item) {
        String key = "Order:" + item.getOrderId() + ":SpecId" + item.getSpecId();
        WmsGiftDto wmsGiftDto = (WmsGiftDto) redisTemplate.opsForValue().get(key);
        if (wmsGiftDto != null) {
            wmcStorageFeignApi.updateWmsGift(wmsGiftDto);
            redisTemplate.delete(key);
        } else {
            WmsGiftDto wmsGift = new WmsGiftDto();
            wmsGift.setGiftId(item.getGiftId());
            wmsGift.setOutNumber(item.getGoodsNum());
            wmcStorageFeignApi.updateWmsGift(wmsGift);
        }
    }

    @Override
    public Wrapper<OdsOrder> doCouponCount(OdsOrder order) {
        //先判断该优惠券能否使用
        Long couponReceiveId = order.getCouponReceiveId();
        CmsCouponUserDto cmsCouponUserDto = new CmsCouponUserDto();
        cmsCouponUserDto.setCouponReceiveId(couponReceiveId);
        List<CmsCouponUserDto> cmsCouponReceiveList = cmcFeignApi.getCouponUserListByCondition(cmsCouponUserDto);
        if (cmsCouponReceiveList == null || cmsCouponReceiveList.size() < 1) {
            return WrapMapper.error("没有找到领取的可用优惠券！");
        }


        cmsCouponUserDto = cmsCouponReceiveList.get(0);

        //计算是否达到可用金额

        if (order.getAmountPayable() < cmsCouponUserDto.getMinAmount()) {
            return WrapMapper.error("订单没有达到优惠券最小使用金额！");
        }
        Integer couponDeduceMoney = 0;
        /**
         * 如果优惠券和商品绑定,订单商品是否可用优惠券
         */
        if (cmsCouponUserDto.getSendType().toString().equals(GlobalConstant.CouponType.GOODS_COUPON.toString())) {
            List<CmsCouponGoodsDto> couponspecList = cmcFeignApi.getCouponGoodsByCouponId(cmsCouponUserDto.getCouponId());
            if (couponspecList != null && couponspecList.size() > 0) {
                Integer orderMoney = 0;
                boolean btag = false;
                int num = 0;
                for (CmsCouponGoodsDto item : couponspecList) {
                    for (OdsOrderGoods cmsSpecDto : order.getGoodsList()) {
                        if (item.getSpecId().equals(cmsSpecDto.getSpecId())) {
                            orderMoney += cmsSpecDto.getPayPrice() * cmsSpecDto.getGoodsNum();
                            num += cmsSpecDto.getGoodsNum();
                            btag = true;
                            break;
                        }
                    }
                }

                if (!btag) {
                    return WrapMapper.error("订单没有优惠券指定商品！");
                }
                if (num < cmsCouponUserDto.getMinGoodsAmount()) {
                    return WrapMapper.error("订单商品金额没有达到优惠券指定商品最低数量！");
                }
                if (orderMoney < cmsCouponUserDto.getMinAmount()) {
                    return WrapMapper.error("订单商品金额没有达到优惠券指定商品最低金额！");
                }

                order.setAmountPayable(order.getAmountPayable() - cmsCouponUserDto.getTypeMoney());
                order.setDiscount(order.getDiscount() + cmsCouponUserDto.getTypeMoney());
                couponDeduceMoney = cmsCouponUserDto.getTypeMoney();

                //处理优惠金额均摊到每个商品。

                for (CmsCouponGoodsDto item : couponspecList) {
                    for (OdsOrderGoods cmsSpecDto : order.getGoodsList()) {
                        if (item.getSpecId().equals(cmsSpecDto.getSpecId())) {
                            cmsSpecDto.setPayPrice(Math.round(cmsSpecDto.getPayPrice() - cmsSpecDto.getPayPrice() * cmsCouponUserDto.getTypeMoney() / orderMoney));
                            break;
                        }
                    }
                }

            }

        } else if (cmsCouponUserDto.getSendType().toString().equals(GlobalConstant.CouponType.WINE_COUPON.toString())) {
            //白酒优惠券
            List<CmsCouponGoodsDto> couponspecList = cmcFeignApi.getCouponGoodsByCouponId(cmsCouponUserDto.getCouponId());
            if (couponspecList != null && couponspecList.size() > 0) {
                Integer orderMoney = 0;
                boolean btag = false;
                int num = 0;
                for (CmsCouponGoodsDto item : couponspecList) {
                    for (OdsOrderGoods cmsSpecDto : order.getGoodsList()) {
                        if (item.getSpecId().equals(cmsSpecDto.getSpecId())) {
                            orderMoney = orderMoney + cmsSpecDto.getGoodsPrice() * cmsSpecDto.getGoodsNum();
                            num += cmsSpecDto.getGoodsNum();
                            btag = true;
                            break;
                        }
                    }
                }

                if (!btag) {
                    return WrapMapper.error("订单没有优惠券指定商品！");
                }
                if (num < cmsCouponUserDto.getMinGoodsAmount()) {
                    return WrapMapper.error("订单商品金额没有达到优惠券指定商品最低数量！");
                }
                if (orderMoney < cmsCouponUserDto.getMinAmount()) {
                    return WrapMapper.error("订单商品金额没有达到优惠券指定商品最低金额！");
                }

                System.out.println("使用白酒优惠券，每件白酒减2元");
                order.setAmountPayable(order.getAmountPayable() - cmsCouponUserDto.getTypeMoney() * num);
                order.setDiscount(order.getDiscount() + cmsCouponUserDto.getTypeMoney() * num);
                couponDeduceMoney = cmsCouponUserDto.getTypeMoney() * num;

                for (CmsCouponGoodsDto item : couponspecList) {
                    for (OdsOrderGoods cmsSpecDto : order.getGoodsList()) {
                        if (item.getSpecId().equals(cmsSpecDto.getSpecId())) {
                            cmsSpecDto.setPayPrice(cmsSpecDto.getPayPrice() - cmsCouponUserDto.getTypeMoney());
                            break;
                        }
                    }
                }

            }

        } else {
            for (OdsOrderGoods cmsSpecDto : order.getGoodsList()) {
                float rate = (float) cmsCouponUserDto.getTypeMoney() / order.getAmountPayable();
                cmsSpecDto.setPayPrice(Math.round(cmsSpecDto.getPayPrice() * (1 - rate)));
            }

            order.setAmountPayable(order.getAmountPayable() - cmsCouponUserDto.getTypeMoney());
            order.setDiscount(order.getDiscount() + cmsCouponUserDto.getTypeMoney());
            couponDeduceMoney = cmsCouponUserDto.getTypeMoney();
        }

        System.out.println("优惠券金额：" + couponDeduceMoney);

        order.setCouponMoney(couponDeduceMoney);

        //如果有包邮优惠券
        if (cmsCouponUserDto.getSendType().toString().equals(GlobalConstant.CouponType.EXPRESS_COUPON.toString()) && order.getFreightPayable() != null) {
            order.setWeight(0);
            order.setDiscount(order.getDiscount() + order.getFreightPayable());
            order.setCouponMoney(order.getFreightPayable());
        } else {
            if (order.getFreightPayable() != null) {
                order.setAmountPayable(order.getAmountPayable() + order.getFreightPayable());

            } else {
                order.setAmountPayable(order.getAmountPayable());
            }
        }

        return WrapMapper.ok(order);
    }

    @Override
    public Wrapper<OdsOrder> doRedCount(OdsOrder order) {
        for (OdsOrderGoods cmsSpecDto : order.getGoodsList()) {
            if (cmsSpecDto.getPayPrice() != null && cmsSpecDto.getPayPrice() > 0) {
                float rate = (float) order.getRedMoney() / order.getAmountPayable();
                cmsSpecDto.setPayPrice(Math.round(cmsSpecDto.getPayPrice() * (1 - rate)));
            }
        }
        if (order.getAmountPayable() > 0){
            order.setAmountPayable(order.getAmountPayable() - order.getRedMoney());
            order.setDiscount(order.getDiscount() + order.getRedMoney());
        }else{
            order.setRedMoney(0);
        }


        return WrapMapper.ok(order);
    }

    @Override
    public Wrapper updateOrderInfo(@ApiParam(name = "odsOrder", value = "需要修改的内容") @RequestBody OdsOrder odsOrder) {
        System.out.println("用户订单修改:" + odsOrder);

        Long orderId = odsOrder.getOrderId();
        OdsOrder newOrder = odsOrderService.findById(orderId);
        if (newOrder == null) {
            return WrapMapper.error("未找到订单！");
        }

        OdsOrderGoods odsOrderGoods = new OdsOrderGoods();
        odsOrderGoods.setOrderId(orderId);
        List<OdsOrderGoods> select = odsOrderGoodsService.select(odsOrderGoods);
        if (select == null || select.size() < 1) {
            return WrapMapper.error("未找到商品！");
        }

        List<OdsOrderGoods> orderGoodsDtos = odsOrder.getGoodsList();
        Iterator<OdsOrderGoods> iterator = select.iterator();// 老订单
        while (iterator.hasNext()) {
            OdsOrderGoods oldGoods = iterator.next();
            boolean newFlag = true;
            //新订单
            for (OdsOrderGoods item : orderGoodsDtos) {
                //新老订单有相同商品 更新
                if (oldGoods.getSpecId().equals(item.getSpecId())) {
                    item.setOrderGoodsId(oldGoods.getOrderGoodsId());
                    odsOrderGoodsService.update(item);

                    //当数量有变更时，修改库存锁定
                    if (!oldGoods.getGoodsNum().equals(item.getGoodsNum())) {
                        Integer num = oldGoods.getGoodsNum() - item.getGoodsNum();
                        changeLockNumber(odsOrder.getWarehouseId(), item.getSpecId(), num);
                        if (item.getGoodsStatus().toString().equals("4")) {
                            item.setGoodsNum(num);
                            odsPayOrderService.changeGiftNumber(oldGoods);
                        }
                    }
                    orderGoodsDtos.remove(item); //新订单移除和老订单相同的商品
                    newFlag = false;
                    break;
                }
            }

            if (newFlag) {
                //老订单的商品，新订单没有了，老订单的商品要删除，退库存
                iterator.remove();
                //oldGoods.setGoodsStatus((byte)5);
                //odsOrderGoodsService.update(oldGoods);
                odsOrderGoodsService.delete(oldGoods);
                //退库存锁定
                changeLockNumber(odsOrder.getWarehouseId(), oldGoods.getSpecId(), -oldGoods.getGoodsNum());
                if (oldGoods.getGoodsStatus().toString().equals("4")) {

                    odsPayOrderService.changeGiftNumber(oldGoods);

                }
            }

        }
        //新订单有，老版本无的商品加入
        if (orderGoodsDtos.size() > 0) {
            for (OdsOrderGoods item : orderGoodsDtos) {

                item.setOrderId(orderId);
                odsOrderGoodsService.save(item);
                //锁定库存
                changeLockNumber(odsOrder.getWarehouseId(), item.getSpecId(), item.getGoodsNum());

                if (item.getGoodsStatus().toString().equals("4")) {

                    odsPayOrderService.changeGiftNumber(item);

                }
            }
        }
        //修改订单信息
        odsOrderService.update(odsOrder);
        return WrapMapper.ok();
    }

    private void changeLockNumber(Long warehouseId, Long specId, Integer goodsNum) {

        StorageDto storageDto = new StorageDto();
        storageDto.setWarehouseId(warehouseId);
        storageDto.setSpecId(specId);
        storageDto.setLockNumber(goodsNum);

        wmcStorageFeignApi.updateStorageNum(Arrays.asList(storageDto));
    }

}
